package scau.zzf.service.Impl;

import org.springframework.beans.factory.annotation.Autowired;
import scau.zzf.base.common.IBaseMapper;
import scau.zzf.base.common.IBaseService;
import scau.zzf.base.util.Reflections;
import tk.mybatis.mapper.entity.Example;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Created by zzf on 2016/11/21.
 */
public abstract class AbstractBaseService<T> implements IBaseService<T> {
    @SuppressWarnings("SpringJavaAutowiringInspection")
    @Autowired
    protected IBaseMapper<T> baseMapper;

    protected Class<?> mapperClass;

    public AbstractBaseService() {
        mapperClass = Reflections.getClassGenricType(this.getClass());
    }

    public int updateSelectProperties(T entity, List<String> propertyList, List valueList) {
        Example example = new Example(mapperClass);
        //使用条件进行更新
        Example.Criteria criteria = example.createCriteria();
        if (propertyList.isEmpty() || valueList.isEmpty()) {
            throw new RuntimeException("valueList 或者 propertyList 不能为空");
        }
        if (propertyList.size() != valueList.size()) {
            throw new RuntimeException("valueList propertyList 大小必须相等");
        }
        for (int e = 0; e < propertyList.size(); ++e) {
            //写入条件,如username=zzf
            criteria.andEqualTo(propertyList.get(e), valueList.get(e));
        }

        return baseMapper.updateByExampleSelective(entity, example);
    }


    public T findByKey(Object key) {
        return baseMapper.selectByPrimaryKey(key);
    }

    public int add(T entity) {
        return baseMapper.insertSelective(entity);
    }

//    public void addBatch(List<T> tList) {
//        baseMapper.insertList(tList);
//    }

    public int delete(Object key) {
        return baseMapper.deleteByPrimaryKey(key);
    }

    public int update(T entity) {
        return baseMapper.updateByPrimaryKey(entity);
    }

    public int updateNotNull(T entity) {
        return baseMapper.updateByPrimaryKeySelective(entity);
    }

    public int updateById(T entity) {
        return baseMapper.updateByPrimaryKey(entity);
    }


    public int updateSelectProperties(T entity, String propertyName, Object value) {
        Example example = new Example(mapperClass);
        //使用条件进行更新
        Example.Criteria criteria = example.createCriteria();
        if (propertyName == null) {
            throw new RuntimeException("propertyName不能为空!");
            //写入条件,如username=zzf
        }
        criteria.andEqualTo(propertyName, value);
        return baseMapper.updateByExampleSelective(entity, example);
    }

    public List<T> find(T entity) {
        return baseMapper.select(entity);
    }

    public T findOne(T entity) {
        return baseMapper.selectOne(entity);
    }

    @Deprecated
    public List<T> findProperties(String condition, String... propertyName) throws Exception {
        Example example = new Example(mapperClass);
        Example.Criteria criteria = example.createCriteria();
        example.selectProperties(propertyName);
        criteria.andCondition(condition);
        return baseMapper.selectByExample(example);
    }


    public List<T> findSelectPropertyWhereAnd(List<String> propertyList, List valueList, String... selectProperties) {
        Example example = new Example(mapperClass);
        if (selectProperties.length >= 1) {
            example.selectProperties(selectProperties);
        }
        //不填selectProperties则select全部列
        return baseMapper.selectByExample(whereAnd(example, propertyList, valueList));
    }

    public T findOneWithAnd(List<String> propertyList, List valueList, String... selectProperties) {
        Example example = new Example(mapperClass);
        if (selectProperties.length >= 1) {
            example.selectProperties(selectProperties);
        }
        //不填selectProperties则select全部列
        List<T> list = baseMapper.selectByExample(whereAnd(example, propertyList, valueList));
        if (list.isEmpty()) {
            throw new NullPointerException();
        }
        return list.get(0);
    }


    public List<T> findSelectPropertyWhereAnd(String propertyName, Object value, String... selectProperties) {
        Example example = new Example(mapperClass);
        example.selectProperties(selectProperties);
        if (selectProperties.length >= 1) {
            example.selectProperties(selectProperties);
        }
        //不填selectProperties则select全部列
        return baseMapper.selectByExample(whereAnd(example, propertyName, value));
    }

    public List<T> findSelectPropertyWhereAnd(String propertyName, Object value, String orderProp, Integer way, String... selectProperties) {
        Example example = new Example(mapperClass);
        example.selectProperties(selectProperties);
        if (selectProperties.length >= 1) {
            example.selectProperties(selectProperties);
        }
        //不填selectProperties则select全部列

        if (orderProp != null) {
            if (way != null && way == 1) {
                example.orderBy(orderProp).asc();
            }
            if (way != null && way == 0) {
                example.orderBy(orderProp).desc();
            }
        }


        return baseMapper.selectByExample(whereAnd(example, propertyName, value));
    }

    public T findOneWithAnd(String propertyName, Object value, String... selectProperties) {
        Example example = new Example(mapperClass);
        example.selectProperties(selectProperties);
        if (selectProperties.length >= 1) {
            example.selectProperties(selectProperties);
        }
        //不填selectProperties则select全部列
        List<T> list = baseMapper.selectByExample(whereAnd(example, propertyName, value));
        if (list.isEmpty()) {
            throw new NullPointerException();
        }
        return list.get(0);
    }


    public List<T> findSelectPropertyWhereOr(String property, String[] value, String... selectProperty) {
        Example example = new Example(mapperClass);
        //使用条件查询
        Example.Criteria criteria = example.createCriteria();
        for (int e = 0; e < selectProperty.length; ++e) {
            //写入查询属性
            example.selectProperties(selectProperty);
        }

        criteria.andLike(property, value[0]);
        if (value.length >= 2) {
            for (int i = 1; i < value.length; i++) {
                example.or().andEqualTo(property, value[i]);
            }
        }
        return baseMapper.selectByExample(example);
    }

    public List<T> findSelectPropertyWhereOr(String[] property, String value, String... selectProperty) {
        Example example = new Example(mapperClass);
        //使用条件查询
        Example.Criteria criteria = example.createCriteria();
        for (int e = 0; e < selectProperty.length; ++e) {
            //写入查询属性
            example.selectProperties(selectProperty);
        }
        criteria.andLike(property[0], value);
        if (property.length >= 2) {
            for (int i = 1; i < property.length; i++) {
                example.or().andEqualTo(property[i], value);
            }
        }
        return baseMapper.selectByExample(example);
    }

    public List<T> findSelectPropertyWhereOrAnd(String[] orProperty, String orValue, String andProperty, Object andValue, String... selectProperty) {
        Example example = new Example(mapperClass);
        //使用条件查询
        Example.Criteria criteria = example.createCriteria();
        for (int e = 0; e < selectProperty.length; ++e) {
            //写入查询属性
            example.selectProperties(selectProperty);
        }
        example.or().andLike(orProperty[0], orValue);
        if (orProperty.length >= 2) {
            for (int i = 1; i < orProperty.length; i++) {
                example.or().andEqualTo(orProperty[i], orValue);
            }
        }
        criteria.andEqualTo(andProperty, andValue);
        return baseMapper.selectByExample(example);
    }

    public List<T> findSelectPropertyWhereOrAnd(String[] orProperty, String orValue, String[] andProperty, Object[] andValue, String... selectProperty) {
        Example example = new Example(mapperClass);
        //使用条件查询
        Example.Criteria criteria = example.createCriteria();

        criteria.andLike(orProperty[0], orValue);
        if (orProperty.length >= 2) {
            for (int i = 1; i < orProperty.length; i++) {
                example.or().andEqualTo(orProperty[i], orValue);
            }
        }
        for (int i = 0; i < andProperty.length; i++) {
            criteria.andEqualTo(andProperty[i], andValue[i]);
        }
        if (selectProperty[0] != null && selectProperty[0].equals("*")) {
            return baseMapper.selectByExample(example);
        }
        for (int e = 0; e < selectProperty.length; ++e) {
            //写入查询属性
            example.selectProperties(selectProperty);
        }
        return baseMapper.selectByExample(example);
    }

    public List<T> findWhereIn(String propertyName, Iterable value) {
        Example example = new Example(mapperClass);
        //使用条件查询
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn(propertyName, value);
        return baseMapper.selectByExample(example);
    }


    public List<T> list(Object key) {
        return baseMapper.selectAll();
    }

    public int findCount(T entity) {
        return baseMapper.selectCount(entity);
    }

    public int findCountByCondition(String value, String... propertyName) {
        Example example = new Example(mapperClass);
        //使用条件查询
        Example.Criteria criteria = example.createCriteria();

        if (propertyName != null && propertyName.length == 1) {
            criteria.andLike(propertyName[0], "%" + value + "%");

        } else if (propertyName != null && propertyName.length > 1) {
            criteria.andLike(propertyName[0], "%" + value + "%");
            for (int i = 1; i < propertyName.length; i++) {
                Example.Criteria criteria1 = example.or();
                criteria1.andLike(propertyName[i], "%" + value + "%");
            }
        } else {
            throw new RuntimeException("propertyName不能为空!");
        }

        return baseMapper.selectCountByExample(example);
    }

    //可通过一个或多个属性值条件进行查询，参数之间要一一对应
    public List<T> findByProperties(List<String> valueList, String... propertyName) {
        Example example = new Example(mapperClass);
        //使用条件查询
        Example.Criteria criteria = example.createCriteria();
        if (propertyName != null && propertyName.length > 1) {
            if (valueList.isEmpty()) {
                throw new RuntimeException("valueList 不能为空");
            }
            for (int e = 0; e < propertyName.length; ++e) {
                //写入条件,如username=zzf
                criteria.andEqualTo(propertyName[e], valueList.get(e));
            }
        } else if (propertyName.length == 1) {
            for (int i = 0; i < valueList.size(); i++) {
                criteria.andEqualTo(propertyName[0], valueList.get(i));
            }
        } else {
            throw new RuntimeException("propertyName不能为空!");
        }
        return baseMapper.selectByExample(example);
    }

    public int deleteByIds(String... idArray) {
        Example example = new Example(mapperClass);
        //使用条件查询
        Example.Criteria criteria = example.createCriteria();

        Set<String> set = new HashSet<>();
        set.addAll(Arrays.asList(idArray));
        criteria.andIn("id", set);
        return baseMapper.deleteByExample(example);
    }

    /**
     * @param ids ,隔开
     */
    public void deleteByIds(String ids) {

        String[] idArray = ids.split(",");
        deleteByIds(idArray);
    }

    public int deleteWhereAnd(String propertyName, String id) {
        Example example = new Example(mapperClass);
        //使用条件查询
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo(propertyName, id);
       return baseMapper.deleteByExample(example);
    }


    public List<T> listSelectPropertiesByCondition(String[] propertyNames, String condition, String... selectProperties) {
        Example example = new Example(mapperClass);
        example.selectProperties(selectProperties);
        Example.Criteria criteria = example.createCriteria();
        if (propertyNames != null && propertyNames.length >= 1) {
            criteria.andLike(propertyNames[0], condition + "%");
            for (int e = 1; e < propertyNames.length; ++e) {
                Example.Criteria criteria1 = example.or();
                criteria1.andLike(propertyNames[e], condition + "%");
            }

        } else {
            throw new RuntimeException("propertyName 不能为空");
        }
        return baseMapper.selectByExample(example);

    }

    public List<T> findAll() {
        return baseMapper.selectAll();
    }


    private Example whereAnd(Example example, List<String> propertyList, List valueList) {
        if (valueList.isEmpty()) {
            throw new RuntimeException("value 不能为空");
        }
        Example.Criteria criteria = example.createCriteria();
        for (int i = 0; i < propertyList.size(); i++) {
            criteria.andEqualTo(propertyList.get(i), valueList.get(i));
        }
        return example;
    }


    private Example whereAnd(Example example, String propertyName, Object value) {
        if (value == null) {
            throw new RuntimeException("value 不能为空");
        }
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo(propertyName, value);
        return example;
    }

    public Example findExample() {
        Example example = new Example(mapperClass);
        return example;
    }

    public List<T> listByExample(Example example) {
        return baseMapper.selectByExample(example);
    }


}
